package features.advance.leetcode.geometry;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Solution1371 {
    /**
     * 给你一个字符串 s ，请你返回满足以下条件的最长子字符串的长度：每个元音字母，即 'a'，'e'，'i'，'o'，'u' ，在子字符串中都恰好出现了偶数次。
     *
     *  
     *
     * 示例 1：
     *
     * 输入：s = "eleetminicoworoep"
     * 输出：13
     * 解释：最长子字符串是 "leetminicowor" ，它包含 e，i，o 各 2 个，以及 0 个 a，u 。
     * 示例 2：
     *
     * 输入：s = "leetcodeisgreat"
     * 输出：5
     * 解释：最长子字符串是 "leetc" ，其中包含 2 个 e 。
     * 示例 3：
     *
     * 输入：s = "bcbcbc"
     * 输出：6
     * 解释：这个示例中，字符串 "bcbcbc" 本身就是最长的，因为所有的元音 a，e，i，o，u 都出现了 0 次。
     *  
     *
     * 提示：
     *
     * 1 <= s.length <= 5 x 10^5
     * s 只包含小写英文字母。
     *
     * 来源：力扣（LeetCode）
     * 链接：https://leetcode-cn.com/problems/find-the-longest-substring-containing-vowels-in-even-counts
     * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
     */

    public int findTheLongestSubstring(String s) {
        long start = System.currentTimeMillis();
        System.out.println(s.length());
        int n = s.length();
        int[] pos = new int[1 << 5];
        Arrays.fill(pos, -1);
        int ans = 0, status = 0;
        pos[0] = 0;
        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);
            if (ch == 'a') {
                // 1
                // 00001
                status ^= (1 << 0);
            } else if (ch == 'e') {
                // 2
                // 00010
                status ^= (1 << 1);
            } else if (ch == 'i') {
                // 4
                // 00100
                status ^= (1 << 2);
            } else if (ch == 'o') {
                // 8
                // 01000
                status ^= (1 << 3);
            } else if (ch == 'u') {
                // 16
                // 10000
                status ^= (1 << 4);
            }
            if (pos[status] >= 0) {
                /**
                 * 考虑枚举字符串的每个位置 i ，计算以它结尾的满足条件的最长字符串长度。
                 * 其实我们要做的就是快速找到最小的 j∈[0,i)，
                 * 满足 pre[i][k]-pre[j][k]（即每一个元音字母出现的次数）均为偶数，
                 * 那么以 i 结尾的最长字符串 s[j+1,i]长度就是 i-j。
                 *
                  */
                //如果status对应的pos[status]大于0 说明已经找到符合要求的子串
                //因为两个子串的奇偶性相等，说明中间子串是符合要求的。
                //奇偶性相同的两个数的差，必定为偶数 只会有一个偶数00000
                //因此出现两个相同状态的数，他们中间必定出现了偶数次数的aeiou
                ans = Math.max(ans, i + 1 - pos[status]);
            } else {
                //pos[status]==-1 说明status是第一次出现，只保存这个值
                pos[status] = i + 1;
            }
        }
        return ans;
    }

    public List<String> funcNoVowelList(String s){
        String reg = "[a|e|i|o|u]";
        String reg2 = "[^aeiou]";
        String[] split = s.split(reg);
        List<String> noVowelList = Arrays.stream(split).filter(e -> !"".equals(e)).collect(Collectors.toList());
        return noVowelList;
    }
    public List<String> funcVowelList(String s){
        String reg2 = "[^aeiou]";
        String[] split2 = s.split(reg2);
        List<String> vowelList = Arrays.stream(split2).filter(e -> !"".equals(e)).collect(Collectors.toList());
        return vowelList;
    }
    public List<String> func(String s){
        String reg = "[a|e|i|o|u]";
        String reg2 = "[^aeiou]";
        String[] split = s.split(reg);
        String[] split2 = s.split(reg2);
        List<String> vowelList = Arrays.stream(split2).filter(e -> !"".equals(e)).collect(Collectors.toList());
        int sum = vowelList.stream().mapToInt(e -> e.length()).sum();

        List<String> noVowelList = Arrays.stream(split).filter(e -> !"".equals(e)).collect(Collectors.toList());
        List<String> list = new ArrayList<>();
        boolean init = "".equals(split[0]);
        for (int i = 0,j=0; i < noVowelList.size(); i++) {
            if(init){
                if(j< vowelList.size()){
                    list.add(vowelList.get(j++));
                }
                list.add(noVowelList.get(i));
            }else{
                list.add(noVowelList.get(i));
                if(j< vowelList.size()){
                    list.add(vowelList.get(j++));
                }
            }
        }
        return list;
    }

    public static boolean isEven(String substring){

        int aCount = substring.length() - substring.replaceAll("a", "").length();
        int eCount = substring.length() - substring.replaceAll("e", "").length();
        int iCount = substring.length() - substring.replaceAll("i", "").length();
        int oCount = substring.length() - substring.replaceAll("o", "").length();
        int uCount = substring.length() - substring.replaceAll("u", "").length();
        return aCount % 2 == 0
                && eCount % 2 == 0
                && iCount % 2 == 0
                && oCount % 2 == 0
                && uCount % 2 == 0;
    }

    public static int sumAEIOU(String substring){
        int aCount = substring.length() - substring.replaceAll("a", "").length();
        int eCount = substring.length() - substring.replaceAll("e", "").length();
        int iCount = substring.length() - substring.replaceAll("i", "").length();
        int oCount = substring.length() - substring.replaceAll("o", "").length();
        int uCount = substring.length() - substring.replaceAll("u", "").length();
        return aCount + eCount + iCount + oCount + uCount;
    }
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        String s = "avecjdkjkde";
        int theLongestSubstring = new Solution1371().findTheLongestSubstring(s);
        System.out.println(theLongestSubstring);
        System.out.println(System.currentTimeMillis() - start);
    }


}
